home *** CD-ROM | disk | FTP | other *** search
- /*────────────────────────────────────────────────────
-
- VGA POLYGONS - 4th in the VGA Programing tutorial
- by Barny Mercer
-
- ────────────────────────────────────────────────────*/
-
- #include "..\include\vgafunc.cpp"
- #include "..\include\pallfunc.cpp"
- // #include "..\include\polyfunc.cpp"
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
-
- // define polygon structure
- struct Point2D{ int X, Y; };
- static int StartX[200], EndX[200];
-
- void DrawFillPolygon( Point2D *Polygon, int NumPoints, int Colour );
- void DrawFastFillPolygon( Point2D *Polygon, int NumPoints, int Colour );
- void PolyLine(int x1, int y1, int x2, int y2);
- void HorizLine( int Start, int End, int Y, unsigned char Col );
- void intro(void);
- void outro(void);
- void DrawRandomPolys();
-
- void main(void)
- {
- intro();
-
- VidMode(VID_320x200);
-
- DrawRandomPolys();
-
- VidMode(VID_TEXT);
-
- outro();
- }
-
- void DrawFillPolygon( Point2D *Polygon, int NumPoints, int Colour )
- {
- int i;
- Point2D *NowPoint, *NextPoint;
-
- NowPoint = Polygon;
- NextPoint = Polygon + 1;
-
- // clear polygon edge arrays
- for (i=0; i<200; i++)
- {
- StartX[i] = -32000;
- EndX[i] = -32000;
- }
-
- for (i=1; i<NumPoints; i++)
- {
- PolyLine( NowPoint->X, NowPoint->Y, NextPoint->X, NextPoint->Y );
-
- NowPoint++;
- NextPoint++;
- }
-
- // now calculate last edge
- NextPoint = Polygon;
-
- PolyLine( NowPoint->X, NowPoint->Y, NextPoint->X, NextPoint->Y);
-
- for (i=0; i<200; i++)
- {
- if (StartX[i] != -32000)
- {
- if (EndX[i] == -32000)
- EndX[i] = StartX[i];
-
- DrawLine( StartX[i], i, EndX[i], i, Colour, vga );
- }
- }
- }
-
- void DrawFastFillPolygon( Point2D *Polygon, int NumPoints, int Colour )
- {
- int i;
- Point2D *NowPoint, *NextPoint;
-
- NowPoint = Polygon;
- NextPoint = Polygon + 1;
-
- // clear polygon edge arrays
- for (i=0; i<200; i++)
- {
- StartX[i] = -32000;
- EndX[i] = -32000;
- }
-
- for (i=1; i<NumPoints; i++)
- {
- PolyLine( NowPoint->X, NowPoint->Y, NextPoint->X, NextPoint->Y );
-
- NowPoint++;
- NextPoint++;
- }
-
- // now calculate last edge
- NextPoint = Polygon;
-
- PolyLine( NowPoint->X, NowPoint->Y, NextPoint->X, NextPoint->Y);
-
- for (i=0; i<200; i++)
- {
- if (StartX[i] != -32000)
- {
- if (EndX[i] == -32000)
- EndX[i] = StartX[i];
-
- HorizLine( StartX[i], EndX[i], i, Colour );
- }
- }
- }
-
- void PolyLine(int x1, int y1, int x2, int y2)
- {
- int tmp, y;
- long x, m;
-
- if (y2 != y1)
- {
- if (y2 < y1)
- {
- // swap values
- tmp = y1;
- y1 = y2;
- y2 = tmp;
-
- tmp = x1;
- x1 = x2;
- x2 = tmp;
- }
-
- x = (long)x1<<8; // multiply x by 256
-
- m = ((long)(x2-x1)<<8)/((long)(y2-y1)); // gradient of line
-
- x += m;
- y1++;
-
- for (y=y1; y<=y2; y++)
- {
- if ((y>=0) & (y<200)) // if co-ordinate is on screen
- if (StartX[y] == -32000)
- StartX[y] = x>>8;
- else
- EndX[y] = x>>8;
-
- x+=m;
- }
- }
- }
-
- void HorizLine( int Start, int End, int Y, unsigned char Col )
- {
- int Diff, Dir;
-
- _asm
- {
- mov [Dir], 1
-
- mov AX, [End]
- sub AX, [Start]
- mov [Diff], AX
-
- cmp [Diff], 0x00 ; we don't even want to bother trying to
- jz Finish ; plot a line with no length
-
- cmp [Diff], 0x00
- jg Continue
-
- mov [Dir], 0xFFFF
-
- Continue:
-
- mov ax, 0xA000
- mov es, ax
- xor di, di
-
- mov bx, [Start] ; co-ordinates
- mov dx, [Y]
- add di, bx
- mov bx, dx
- shl dx, 8
- shl bx, 6
- add dx, bx
- add di, dx
- mov al, [Col]
-
- mov cx, [Diff]
-
- Again:
- mov es:[di], al ; put pixel at first point - address in ES:DI, colour in AL
- add di, [Dir]
-
- sub cx, [Dir]
- cmp cx, 0
- jnz Again
- Finish:
- }
- }
-
- void intro()
- {
- VidMode( VID_TEXT );
-
- printf( "Hello & welcome to this, the fourth of my VGA programming tutorials\n" );
- printf( "───────────────────────────────────────────────────────────────────\n\n" );
- printf( "This edition concerns it's self with drawing filled polygons.\n");
- printf( "The process is quite simple and quite a fast routine can be developed.\n");
- printf( "\nThe first routine uses the standard line algorithm developed in Tutorial 2\n");
- printf( "The second uses an optimised line routine (written in assembler)\n");
- printf( "\n\nI will draw polygons for 10 seconds and then let you know how many have\n" );
- printf( "been drawn. Please note that the number of polygons per second can vary greatly\n");
- printf( "from one run to the next, so don't take these values as gospel. Also note that ");
- printf( "this is by no means the fastest polygon routine around, strive for more speed.\n" );
- printf( "It should be easy to improve." );
- printf( "\n\nTake a look.....\n");
-
- getch();
- }
-
- void outro()
- {
- VidMode( VID_TEXT );
-
- printf( "And there you have it! Simple yet effective.\n\n");
- printf( "HELP! I don't know what to do for tutorial 5! Help me out here!\n");
- printf( "What would you like to see? What areas of graphics programming interest you?\n\n");
- printf( "Write to me at : barny.mercer@zetnet.co.uk\n\n");
- printf( " while (!MailConcerningTutorial5Recieved())\n" );
- printf( " { \n" );
- printf( " PanicLots(); \n" );
- printf( " }\n\n" );
- printf( " BreathSighOfRelief(); \n" );
- printf( " ProfuselyThankPersonWhoMadeSuggestion(); \n\n" );
- printf( "Well... not strictly true, I do have a few ideas, but I would still like some\ninput." );
- printf( "\n\nUntil next time.....\n\n");
- }
-
- void DrawRandomPolys(void)
- {
- Point2D Polygon[3];
- time_t stime;
- time_t NowTime;
-
- printf( "Original line routine...." );
- getch();
-
- // number of polygons drawn
- unsigned int NumPolys=0;
-
- // begin timing
- time( &stime );
- NowTime = stime;
-
- while( NowTime < (stime+10) )
- {
- for (int nTmp=0; nTmp<3; nTmp++)
- {
- Polygon[nTmp].X = (rand()%319);
- Polygon[nTmp].Y = (rand()%199);
- }
-
- DrawFillPolygon( Polygon, 3, rand()%256 );
-
- NumPolys++;
- time( &NowTime );
- }
-
- // check time at end
- time( &NowTime );
-
- // clear keyboard buffer
- getch();
-
- VidMode( VID_TEXT );
- printf( "That's %d polygons in 10 seconds", NumPolys );
- printf( "\nAbout %d polys per second", (NumPolys/10) );
- getch();
-
- // faster polygon routine
- VidMode( VID_320x200 );
- printf( "Optimised line aglorithm...." );
- getch();
-
- // begin timing
- time( &stime );
- NowTime = stime;
-
- while( NowTime < (stime+10) )
- {
- for (int nTmp=0; nTmp<3; nTmp++)
- {
- Polygon[nTmp].X = (rand()%319);
- Polygon[nTmp].Y = (rand()%199);
- }
-
- DrawFillPolygon( Polygon, 3, rand()%256 );
-
- NumPolys++;
- time( &NowTime );
- }
-
- // check time at end
- time( &NowTime );
-
- getch();
-
- VidMode( VID_TEXT );
- printf( "That's %d polygons in 10 seconds", NumPolys );
- printf( "\nAbout %d polys per second", (NumPolys/10) );
- getch();
- }
-